package cn.com.hhrcw.enterprise.service.impl;

import cn.com.hhrcw.enterprise.params.EnRecruitParams;
import cn.com.hhrcw.enterprise.params.EnRegInfoParams;
import cn.com.hhrcw.enterprise.service.EnterpriseService;
import cn.com.hhrcw.enterprise.vo.OpJobVO;
import cn.com.hhrcw.enterprise.vo.ResumeInfoVO;
import cn.com.hhrcw.enterprise.vo.SsDataInfoVO;
import cn.com.hhrcw.enterprise.vo.UserInfoVo;
import cn.com.hhrcw.entity.*;
import cn.com.hhrcw.mapstruct.*;
import cn.com.hhrcw.service.*;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.PasswordUtil;
import org.jeecg.common.util.oConvertUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @program: recruit-boot-parent
 * @author: JD
 * @create: 2020-11-03 15:56
 **/
@Service("entEnterpriseServiceImpl")
@Slf4j
public class EnterpriseServiceImpl implements EnterpriseService {

    @Autowired
    IPiInfoService piInfoService;

    @Autowired
    ICvResumeService resumeService;

    @Autowired
    private EnCvResumeConvert enCvResumeConvert;

    @Autowired
    private ICvWorkIntentionService cvWorkIntentionService;

    @Autowired
    private EnCvWorkIntentionConvert enCvWorkIntentionConvert;

    @Autowired
    private ICvUserWorkInfoService cvUserWorkInfoService;

    @Autowired
    private EnCvUserWorkInfoConvert enCvUserWorkInfoConvert;

    @Autowired
    private ICvUserEduInfoService cvUserEduInfoService;

    @Autowired
    private EnCvUserEduInfoConvert enCvUserEduInfoConvert;

    @Autowired
    private ICvProjectInfoService cvProjectInfoService;

    @Autowired
    private EnCvProjectInfoConvert enCvProjectInfoConvert;

    @Autowired
    private ICvTrainService cvTrainService;

    @Autowired
    private EnCvTrainConvert enCvTrainConvert;

    @Autowired
    private ICvLanguageLevelService cvLanguageLevelService;

    @Autowired
    private EnCvLanguageLevelConvert enCvLanguageLevelConvert;

    @Autowired
    private ICvSkillsService cvSkillsService;

    @Autowired
    private EnCvSkillsConvert skillsConvert;

    @Autowired
    private ICvCertificateService cvCertificateService;

    @Autowired
    private EnCvCertificateConvert certificateConvert;

    @Autowired
    private IFileService fileService;

    @Autowired
    private IOpJobService jobService;

    @Autowired
    private EnOpJobConvert jobConvert;

    @Autowired
    private IOpDeliveryHistoryService deliveryHistoryService;


    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    IOpInterviewHistoryService interviewHistoryService;

    @Autowired
    private ISysUserDepartService sysUserDepartService;

    @Autowired
    private IEnRecruitService enRecruitService;

    @Autowired
    private IOpEntryHistoryService entryHistoryService;

    @Autowired
    JdbcTemplate jdbcTemplate;

    @Override
    public ResumeInfoVO getResumeInfo(String userId, Integer lanType) {
        ResumeInfoVO result = new ResumeInfoVO();

        CvResume cvResume = resumeService.lambdaQuery().eq(CvResume::getDelFlag, false).eq(CvResume::getUserId, userId).eq(CvResume::getLanType, lanType).one();
        if (cvResume == null) {
            return new ResumeInfoVO();
        }
        String resumeId = cvResume.getId();
        LambdaQueryWrapper<PiInfo> infoQuery = new LambdaQueryWrapper<>();
        infoQuery.eq(PiInfo::getDelFlag, false).eq(PiInfo::getUserId, userId);
        PiInfo info = piInfoService.getOne(infoQuery);

        //个人基本信息
        UserInfoVo userInfo = new UserInfoVo();
        userInfo.setEMail(info.getEmail());
        userInfo.setLocation(info.getLiveCity());
        userInfo.setName(info.getName());
        userInfo.setSex(info.getSex());
        userInfo.setUserId(info.getUserId());
        userInfo.setWorkYears(info.getWorkYears());
        result.setUserInfo(userInfo);

        //基本信息
        result.setResumes(enCvResumeConvert.toVO(cvResume));

        //期望职位
        LambdaQueryWrapper<CvWorkIntention> workIntentionQuery = new LambdaQueryWrapper<>();
        workIntentionQuery.eq(CvWorkIntention::getDelFlag, false).eq(CvWorkIntention::getResumeId, resumeId);
        List<CvWorkIntention> workIntentions = cvWorkIntentionService.list(workIntentionQuery);
        result.setWorkIntentions(enCvWorkIntentionConvert.toVO(workIntentions));

        //工作实习经历
        LambdaQueryWrapper<CvUserWorkInfo> userWorkInfoQuery = new LambdaQueryWrapper<>();
        userWorkInfoQuery.eq(CvUserWorkInfo::getDelFlag, false).eq(CvUserWorkInfo::getResumeId, resumeId);
        List<CvUserWorkInfo> userWorkInfos = cvUserWorkInfoService.list(userWorkInfoQuery);
        result.setUserWorkInfos(enCvUserWorkInfoConvert.toVO(userWorkInfos));

        //教育经历
        LambdaQueryWrapper<CvUserEduInfo> userEduInfoQuery = new LambdaQueryWrapper<>();
        userEduInfoQuery.eq(CvUserEduInfo::getDelFlag, false).eq(CvUserEduInfo::getResumeId, resumeId);
        List<CvUserEduInfo> userEduInfos = cvUserEduInfoService.list(userEduInfoQuery);
        result.setUserEduInfos(enCvUserEduInfoConvert.toVO(userEduInfos));

        //项目经历
        LambdaQueryWrapper<CvProjectInfo> projectInfoQuery = new LambdaQueryWrapper<>();
        projectInfoQuery.eq(CvProjectInfo::getDelFlag, false).eq(CvProjectInfo::getResumeId, resumeId);
        List<CvProjectInfo> projectInfos = cvProjectInfoService.list(projectInfoQuery);
        result.setProjectInfos(enCvProjectInfoConvert.toVO(projectInfos));

        //培训经历
        LambdaQueryWrapper<CvTrain> trainQuery = new LambdaQueryWrapper<>();
        trainQuery.eq(CvTrain::getDelFlag, false).eq(CvTrain::getResumeId, resumeId);
        List<CvTrain> trainInfos = cvTrainService.list(trainQuery);
        result.setTrainInfos(enCvTrainConvert.toVO(trainInfos));

        //语言水平
        LambdaQueryWrapper<CvLanguageLevel> languageLevelQuery = new LambdaQueryWrapper<>();
        languageLevelQuery.eq(CvLanguageLevel::getDelFlag, false).eq(CvLanguageLevel::getResumeId, resumeId);
        List<CvLanguageLevel> languageLevelInfos = cvLanguageLevelService.list(languageLevelQuery);
        result.setLanguageLevelInfos(enCvLanguageLevelConvert.toVO(languageLevelInfos));

        //职业特长与技能（专业技能）
        LambdaQueryWrapper<CvSkills> skillsQuery = new LambdaQueryWrapper<>();
        skillsQuery.eq(CvSkills::getDelFlag, false).eq(CvSkills::getResumeId, resumeId);
        List<CvSkills> skillsInfos = cvSkillsService.list(skillsQuery);
        result.setSkillsInfos(skillsConvert.toVO(skillsInfos));

        //资质证书
        LambdaQueryWrapper<CvCertificate> certificateQuery = new LambdaQueryWrapper<>();
        certificateQuery.eq(CvCertificate::getDelFlag, false).eq(CvCertificate::getResumeId, resumeId);
        List<CvCertificate> certificateInfos = cvCertificateService.list(certificateQuery);
        result.setCertificateInfos(certificateConvert.toVO(certificateInfos));

        File file = fileService.getById(cvResume.getEnclosureId());
        result.setFiles(file);

        return result;
    }

    @Override
    public List<OpJobVO> getJobListBySsId(String ssId) {
        LambdaQueryWrapper<OpJob> jobLambdaQueryWrapper = new LambdaQueryWrapper<>();
        jobLambdaQueryWrapper.eq(OpJob::getDelFlag, false).eq(OpJob::getBsType, 1).eq(OpJob::getBsId, ssId);
        List<OpJob> jobs = jobService.list(jobLambdaQueryWrapper);
        return jobConvert.toVO(jobs);
    }

    @Override
    public SsDataInfoVO getDatInfo(String ssId, String comId) {
        SsDataInfoVO result = new SsDataInfoVO();
        LambdaQueryWrapper<OpJob> jobQuery = new LambdaQueryWrapper<>();
        jobQuery.eq(OpJob::getDelFlag, false).eq(OpJob::getBsId, ssId).eq(OpJob::getBsType, 1).select(OpJob::getId).in(OpJob::getCompanyId, comId);
        List<OpJob> jobs = jobService.list(jobQuery);
        if (!CollectionUtils.isEmpty(jobs)) {
            List<String> jobIds = new ArrayList<>();
            jobs.forEach(e -> {
                jobIds.add(e.getId());
            });
            //学历统计
            LambdaQueryWrapper<OpDeliveryHistory> eduQuery = new LambdaQueryWrapper<>();
            eduQuery.eq(OpDeliveryHistory::getDelFlag, false).in(OpDeliveryHistory::getJobId, jobIds).select(OpDeliveryHistory::getUserId, OpDeliveryHistory::getResumeId);
            List<OpDeliveryHistory> eduList = deliveryHistoryService.list(eduQuery);
            if (!CollectionUtils.isEmpty(eduList)) {
                eduInfoMsg(eduList, result);
            }
            //时间段
            Date todayZero = new Date();
            long zero = cn.com.hhrcw.utils.DateUtil.getTodayZero();
            todayZero.setTime(zero);
            Date lastDayZero = new Date();
            lastDayZero.setTime(zero - 86400000);
            LambdaQueryWrapper<OpDeliveryHistory> todayQuery = new LambdaQueryWrapper<>();
            todayQuery.eq(OpDeliveryHistory::getDelFlag, false).in(OpDeliveryHistory::getJobId, jobIds).ge(OpDeliveryHistory::getCreateTime, todayZero);
            List<OpDeliveryHistory> today = deliveryHistoryService.list(todayQuery);
            //0 未阅读 1 已阅读  2 不合适 3 通过筛选 4  面试 5已发offer(已录用)6 已入职 7 被过滤
            int historiesToday = interviewHistoryService.lambdaQuery().in(OpInterviewHistory::getJobId, jobIds).ge(OpInterviewHistory::getCreateTime, todayZero).count();
            result.setViewCountToday(historiesToday);
            int offerCountToday = entryHistoryService.lambdaQuery().in(OpEntryHistory::getJobId, jobIds).ge(OpEntryHistory::getCreateTime, todayZero).count();
            result.setUseCountToday(offerCountToday);
            if (!CollectionUtils.isEmpty(today)) {
                result.setDeliveryCountToday(today.size());
                today.forEach(e -> {
                    if (e.getState() != null) {
                        boolean flag = 6 == e.getState();
                        if (flag) {
                            result.setEntryCountToday(result.getEntryCountToday() + 1);
                        }
                    }
                });
            }
            //昨日
            LambdaQueryWrapper<OpDeliveryHistory> lastDayQuery = new LambdaQueryWrapper<>();
            lastDayQuery.eq(OpDeliveryHistory::getDelFlag, false).in(OpDeliveryHistory::getJobId, jobIds).ge(OpDeliveryHistory::getCreateTime, lastDayZero).lt(OpDeliveryHistory::getCreateTime, todayZero);
            List<OpDeliveryHistory> lastDay = deliveryHistoryService.list(lastDayQuery);
            int historiesLastDay = interviewHistoryService.lambdaQuery().in(OpInterviewHistory::getJobId, jobIds).ge(OpInterviewHistory::getCreateTime, lastDayZero).lt(OpInterviewHistory::getCreateTime, todayZero).count();
            result.setViewCountLastDay(historiesLastDay);
            int offerCount = entryHistoryService.lambdaQuery().in(OpEntryHistory::getJobId, jobIds).ge(OpEntryHistory::getCreateTime, lastDayZero).lt(OpEntryHistory::getCreateTime, todayZero).count();
            result.setUseCountLastDay(offerCount);
            if (!CollectionUtils.isEmpty(lastDay)) {
                result.setDeliveryCountLastDay(lastDay.size());
                today.forEach(e -> {
                    //0 未阅读  1 已阅读 2 不合适 3通过筛选4 面试 5已发offer(已录用) 6 已入职 7 被系统过滤 8未入职9反馈面试结果(通过)10反馈面试结果(不通过)
                    if (e.getState() != null) {
                        boolean flag = 6 == e.getState();
                        if (flag) {
                            result.setEntryCountLastDay(result.getEntryCountLastDay() + 1);
                        }
                    }
                });
            }
        }
        return result;
    }

    private void eduInfoMsg(List<OpDeliveryHistory> eduList, SsDataInfoVO result) {
        StringBuilder sql = new StringBuilder("SELECT user_id,max(edu_level) as edu_level FROM `cv_user_edu_info` where resume_id in (");
        eduList.forEach(e -> {
            sql.append("'" + e.getResumeId() + "',");
        });
        sql.deleteCharAt(sql.length() - 1).append(") group by user_id");
        List<CvUserEduInfo> eduInfos = jdbcTemplate.query(sql.toString(), new BeanPropertyRowMapper<>(CvUserEduInfo.class));
        //最高学历 0 初中  1 高中 2 中专/中技 3 大专 4 本科 5 硕士 6 MBA/EMBA 7 博士
        if (!CollectionUtils.isEmpty(eduInfos)) {
            eduInfos.forEach(e -> {
                if (e.getEduLevel() != null) {
                    switch (e.getEduLevel()) {
                        case 7:
                            result.setDoctorCount(result.getDoctorCount() + 1);
                            break;
                        case 6:
                            result.setMbaCount(result.getMbaCount() + 1);
                            break;
                        case 5:
                            result.setMasterCount(result.getMasterCount() + 1);
                            break;
                        case 4:
                            result.setUndergraduateCount(result.getUndergraduateCount() + 1);
                            break;
                        case 3:
                            result.setJuniorCollegeCount(result.getJuniorCollegeCount() + 1);
                            break;
                        case 2:
                            result.setSecondaryCount(result.getSecondaryCount() + 1);
                            break;
                        case 1:
                            result.setHighSchoolCount(result.getHighSchoolCount() + 1);
                            break;
                        case 0:
                            result.setMiddleSchoolCount(result.getMiddleSchoolCount() + 1);
                            break;
                        default:
                            break;
                    }
                }
            });
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result addColleague(EnRecruitParams params) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        boolean saved = false;
        SysUser userState = sysUserService.lambdaQuery()
                .eq(SysUser::getPhone, params.getPhone())
                .eq(SysUser::getDelFlag, false)
                .one();
        if (userState == null) {
            SysUser user = getSysUser(sysUser, params);
            saved = sysUserService.save(user);
            SysUserDepart sysUserDepart = new SysUserDepart();
            sysUserDepart.setUserId(user.getId());
            sysUserDepart.setDepId(params.getCompanyId());
            sysUserDepartService.save(sysUserDepart);
            piInfoService.save(getPiInfo(sysUser, user, params));
            enRecruitService.save(getEnRecruit(sysUser, user, params));
        } else {
            PiInfo piInfoState = piInfoService.lambdaQuery()
                    .eq(PiInfo::getUserId, userState.getId())
                    .eq(PiInfo::getDelFlag, false)
                    .one();
            boolean flag = piInfoState.getRoleType().contains("1");
            if (flag) {
                return Result.error("添加失败，对方已加入企业");
            }
            SysUserDepart sysUserDepart = new SysUserDepart();
            sysUserDepart.setUserId(userState.getId());
            sysUserDepart.setDepId(params.getCompanyId());
            saved = sysUserDepartService.save(sysUserDepart);
            String type = piInfoState.getRoleType();
            if (StringUtils.isEmpty(type)) {
                type += "1";
            } else {
                type += ",1";
            }
            LambdaUpdateWrapper<PiInfo> piUpdateWrapper = Wrappers.lambdaUpdate();
            piUpdateWrapper.in(PiInfo::getUserId, userState.getId())
                    .eq(PiInfo::getDelFlag, false)
                    .set(PiInfo::getPhotoId, params.getPhotoId())
                    .set(PiInfo::getName, params.getUserName())
                    .set(PiInfo::getPhone, params.getPhone())
                    .set(PiInfo::getEmail, params.getMailbox())
                    .set(PiInfo::getRoleType, type)
                    .set(PiInfo::getUpdateBy, sysUser.getUsername())
                    .set(PiInfo::getUpdateTime, DateUtil.date());
            piInfoService.update(piUpdateWrapper);
            EnRecruit recruit = enRecruitService
                    .lambdaQuery()
                    .eq(EnRecruit::getUserId, userState.getId())
                    .eq(EnRecruit::getDelFlag, false)
                    .one();
            saveEnRecruit(params, sysUser, userState, recruit);
        }
        return saved ? Result.ok() : Result.error("添加失败");
    }

    private void saveEnRecruit(EnRecruitParams params, LoginUser sysUser, SysUser userState, EnRecruit recruit) {
        if (recruit == null) {
            recruit = new EnRecruit();
            recruit.setCreateBy(sysUser.getId());
            recruit.setCreateTime(DateUtil.date());
            recruit.setDelFlag(false);
            recruit.setUserId(userState.getId());
            recruit.setUserName(params.getUserName());
            recruit.setNickName(params.getNickName());
            recruit.setJob(params.getJob());
            recruit.setDepart(params.getDepart());
            recruit.setPhone(params.getPhone());
            recruit.setMailbox(params.getMailbox());
            enRecruitService.save(recruit);
        } else {
            LambdaUpdateWrapper<EnRecruit> updateWrapper = Wrappers.lambdaUpdate();
            updateWrapper.in(EnRecruit::getUserId, userState.getId())
                    .eq(EnRecruit::getDelFlag, false)
                    .set(EnRecruit::getUserName, params.getUserName())
                    .set(EnRecruit::getNickName, params.getNickName())
                    .set(EnRecruit::getJob, params.getJob())
                    .set(EnRecruit::getDepart, params.getDepart())
                    .set(EnRecruit::getPhone, params.getPhone())
                    .set(EnRecruit::getMailbox, params.getMailbox())
                    .set(EnRecruit::getUpdateBy, sysUser.getUsername())
                    .set(EnRecruit::getUpdateTime, DateUtil.date());
            enRecruitService.update(updateWrapper);
        }
    }

    private SysUser getSysUser(LoginUser sysUser, EnRecruitParams params) {
        SysUser user = new SysUser();
        String salt = oConvertUtils.randomGen(8);
        String passwordEncode = PasswordUtil.encrypt(params.getPhone(), salt, salt);
        user.setCreateBy(sysUser.getId());
        user.setCreateTime(DateUtil.date());
        user.setDelFlag(false);
        user.setSalt(salt);
        user.setUsername(params.getPhone());
        user.setRealname(params.getUserName());
        user.setPassword(passwordEncode);
        user.setEmail(params.getMailbox());
        user.setPhone(params.getPhone());
        user.setCreateTime(DateUtil.date());
        return user;
    }

    private PiInfo getPiInfo(LoginUser sysUser, SysUser user, EnRecruitParams params) {
        PiInfo piInfo = new PiInfo();
        piInfo.setCreateBy(sysUser.getId());
        piInfo.setCreateTime(DateUtil.date());
        piInfo.setDelFlag(false);
        piInfo.setUserId(user.getId());
        piInfo.setRoleType("1");
        piInfo.setPhone(params.getPhone());
        piInfo.setName(params.getUserName());
        piInfo.setEmail(params.getMailbox());
        return piInfo;
    }

    private EnRecruit getEnRecruit(LoginUser sysUser, SysUser user, EnRecruitParams params) {
        EnRecruit recruit = new EnRecruit();
        recruit.setCreateBy(sysUser.getId());
        recruit.setCreateTime(DateUtil.date());
        recruit.setDelFlag(false);
        recruit.setUserId(user.getId());
        recruit.setUserName(params.getUserName());
        recruit.setNickName(params.getNickName());
        recruit.setJob(params.getJob());
        recruit.setDepart(params.getDepart());
        recruit.setPhone(params.getPhone());
        recruit.setMailbox(params.getMailbox());
        return recruit;
    }

    @Autowired
    private IEnInfoService ennfoService;

    @Autowired
    private EnEnInfoConvert enEnInfoConvert;

    @Autowired
    private ISysUserDepartService userDepartService;


    @Autowired
    private IPiInfoService pinfoService;

    @Autowired
    private IEnInfoService enInfoService;


    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result reg(EnRegInfoParams entParams) {
        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        if (null == loginUser) {
            log.warn("null==sysUser");
            return Result.error("注册失败");
        }

        log.info(loginUser.toString());


        PiInfo piInfo = null;
        piInfo = this.pinfoService.lambdaQuery().eq(PiInfo::getUserId, loginUser.getId()).one();
        log.info(piInfo.getEnRoleType() + "查出用户：" + piInfo);
        piInfo.setEmail(entParams.getPersonalEmail());
        piInfo.setName(entParams.getPersonalName());

        piInfo.setEnRoleType(1);
        pinfoService.updateById(piInfo);
        SysUser sysUser = sysUserService.getById(loginUser.getId());
        sysUser.setEmail(entParams.getPersonalEmail());
        sysUser.setRealname(entParams.getPersonalName());
        sysUserService.updateById(sysUser);
        int count = enInfoService.lambdaQuery().eq(EnInfo::getEnName, entParams.getEnName()).eq(EnInfo::getDelFlag, false).count();
        Assert.isFalse(count > 0, "企业名称已存在");
        EnInfo enInfo = enEnInfoConvert.toEntity(entParams);
        enInfo.setCreateBy(sysUser.getId());
        enInfo.setCreateTime(DateUtil.date());
        enInfo.setDelFlag(false);
        enInfo.setState(1);
        enInfo.setActFlag(true);
        enInfo.setPostNum(0);
        enInfo.setDeliverNum(0);
        enInfo.setEnGrade(entParams.getEnGrade());
        enInfo.setAffUnit(entParams.getAffUnit());
        boolean saved = ennfoService.save(enInfo);
        if (saved) {
            userDepartService.referenceUser(loginUser.getId(), enInfo.getId());
        }
        jdbcTemplate.update("insert into sys_depart (id,depart_name,org_category,org_code,create_by,create_time) value (?,?,?,?,?,?)", enInfo.getId(), entParams.getEnName(), "1", " ", sysUser.getId(), new Date());
        SecurityUtils.getSubject().logout();


        return Result.ok("注册成功");

    }

}
